"""
Docling Web应用主文件
"""
import os
import logging
from pathlib import Path
from flask import Flask, request, render_template, jsonify, send_file, flash, redirect, url_for
from werkzeug.utils import secure_filename
from werkzeug.exceptions import RequestEntityTooLarge
import traceback

from config import config
from utils.docling_processor import DoclingProcessor
from utils.model_manager import ModelManager

# 配置详细日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.StreamHandler(),  # 控制台输出
    ]
)

# 设置特定模块的日志级别
logging.getLogger('utils.docling_processor').setLevel(logging.INFO)
logging.getLogger('utils.vlm_processor').setLevel(logging.INFO)
logging.getLogger('utils.model_manager').setLevel(logging.INFO)

# 减少一些第三方库的日志噪音
logging.getLogger('urllib3').setLevel(logging.WARNING)
logging.getLogger('requests').setLevel(logging.WARNING)
logging.getLogger('transformers').setLevel(logging.WARNING)

logger = logging.getLogger(__name__)

def create_app(config_name=None):
    """创建Flask应用"""
    app = Flask(__name__)
    
    # 加载配置
    config_name = config_name or os.environ.get('FLASK_ENV', 'default')
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)
    
    # 初始化模型管理器
    model_manager = ModelManager()
    
    # 初始化Docling处理器
    docling_processor = DoclingProcessor(model_manager)
    
    def allowed_file(filename):
        """检查文件扩展名是否允许"""
        return '.' in filename and \
               filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']
    
    @app.route('/')
    def index():
        """主页"""
        return render_template('index.html')
    
    @app.route('/upload', methods=['POST'])
    def upload_file():
        """文件上传和处理"""
        try:
            # 检查是否有文件
            if 'file' not in request.files:
                return jsonify({'error': '没有选择文件'}), 400
            
            file = request.files['file']
            if file.filename == '':
                return jsonify({'error': '没有选择文件'}), 400
            
            # 检查文件类型
            if not allowed_file(file.filename):
                return jsonify({'error': '不支持的文件类型'}), 400
            
            # 保存文件
            filename = secure_filename(file.filename)
            upload_path = Path(app.config['UPLOAD_FOLDER']) / filename
            file.save(upload_path)

            # 记录文件上传信息
            file_size = upload_path.stat().st_size
            logger.info("=" * 80)
            logger.info("📤 新文件上传")
            logger.info("=" * 80)
            logger.info(f"📄 文件名: {filename}")
            logger.info(f"📊 文件大小: {file_size / (1024*1024):.2f} MB")
            logger.info(f"📁 保存路径: {upload_path}")

            # 获取处理选项
            output_formats = request.form.getlist('output_formats') or ['markdown']
            max_pages = int(request.form.get('max_pages', 50))

            logger.info("⚙️  处理选项:")
            logger.info(f"   - 输出格式: {', '.join(output_formats)}")
            logger.info(f"   - 最大页数: {max_pages}")
            logger.info("=" * 80)

            # 处理文档
            logger.info("🚀 开始文档处理流程...")
            result = docling_processor.process_document(
                file_path=upload_path,
                output_formats=output_formats,
                max_pages=max_pages
            )

            logger.info("🧹 清理临时文件...")
            logger.info("=" * 80)

            # 清理上传的文件
            upload_path.unlink(missing_ok=True)

            return jsonify({
                'success': True,
                'result': result['outputs'],
                'metadata': result['metadata'],
                'filename': filename
            })
            
        except RequestEntityTooLarge:
            return jsonify({'error': '文件太大，请选择小于100MB的文件'}), 413
        except Exception as e:
            logger.error(f"处理文件时出错: {str(e)}")
            logger.error(traceback.format_exc())
            return jsonify({'error': f'处理文件时出错: {str(e)}'}), 500
    
    @app.route('/models/status')
    def models_status():
        """获取模型状态"""
        try:
            status = model_manager.get_models_status()
            return jsonify(status)
        except Exception as e:
            logger.error(f"获取模型状态时出错: {str(e)}")
            return jsonify({'error': str(e)}), 500
    
    @app.route('/models/download', methods=['POST'])
    def download_models():
        """下载模型"""
        try:
            model_manager.download_models()
            return jsonify({'success': True, 'message': '模型下载完成'})
        except Exception as e:
            logger.error(f"下载模型时出错: {str(e)}")
            return jsonify({'error': str(e)}), 500
    
    @app.errorhandler(404)
    def not_found(error):
        return render_template('404.html'), 404
    
    @app.errorhandler(500)
    def internal_error(error):
        return render_template('500.html'), 500
    
    return app

if __name__ == '__main__':
    app = create_app()
    app.run(host='0.0.0.0', port=5000, debug=True)
